﻿using Castle.DynamicProxy;
using Puppy.DynamicProxy;
using System;
using System.Threading.Tasks;

namespace Puppy.Autofac.DynamicProxy
{
    public class CastleAsyncInterceptorAdapter<TInterceptor> : AsyncInterceptorBase
        where TInterceptor : IPuppyInterceptor
    {
        private readonly TInterceptor _Interceptor;

        public CastleAsyncInterceptorAdapter(TInterceptor Interceptor)
        {
            _Interceptor = Interceptor;
        }

        protected async override Task InterceptAsync(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func<IInvocation, IInvocationProceedInfo, Task> proceed)
        {
            await _Interceptor.InterceptAsync(
                new CastleMethodInvocationAdapter(invocation, proceedInfo, proceed)
            );
        }

        protected async override Task<TResult> InterceptAsync<TResult>(IInvocation invocation, IInvocationProceedInfo proceedInfo, Func<IInvocation, IInvocationProceedInfo, Task<TResult>> proceed)
        {
            var adapter = new CastleMethodInvocationAdapterWithReturnValue<TResult>(invocation, proceedInfo, proceed);

            await _Interceptor.InterceptAsync(
                adapter
            );

            return (TResult)adapter.ReturnValue;
        }
    }
}